package com.rex.saas.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rex.saas.bean.BaseResponse;
import com.rex.saas.bean.DeviceBasicData;
import com.rex.saas.bean.ResultCode;
import com.rex.saas.bean.request.AirBatchCmdRequest;
import com.rex.saas.bean.request.AirConCmdRequest;
import com.rex.saas.bean.request.AirConPageRequest;
import com.rex.saas.bean.request.DeviceListRequest;
import com.rex.saas.bean.response.AirConResponse;
import com.rex.saas.bean.response.DeviceResponse;
import com.rex.saas.bean.response.IndexCntNumResponse;
import com.rex.saas.constants.ApiConstant;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.PaasGatewayDeviceRelation;
import com.rex.saas.db.entity.SaasTslModel;
import com.rex.saas.service.*;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/airCon")
public class AirConController extends BaseController{
    @Autowired
    private TslModelService tslModelService;

    @Autowired
    private DeviceService deviceService;


    @Autowired
    private SpaceService spaceService;

    @Autowired
    private RexolarApiClient rexolarApiClient;

    @RequestMapping("/index")
    public BaseResponse index(HttpServletRequest  request, @RequestParam Long spaceId) {
        log.info("cnt ===> spaceId:{}", spaceId);
        String token = request.getHeader("token");
        BaseResponse validateSpace = validateSpace(spaceId, token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("airCon validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        String tenantId = JwtUtils.getTenantId( token);
        List<SaasTslModel> tslModelList = tslModelService.queryTslModelByCategoryName(Constants.AIR_CON, tenantId);
        if (CollectionUtils.isEmpty(tslModelList)){
            return BaseResponse.error("空调产品模型不存在", ResultCode.PARAM_ERROR);
        }

        List<DeviceResponse> deviceResponseList = getAirConList(tslModelList, spaceId, token);
        AtomicInteger online = new AtomicInteger();
        AtomicInteger offline = new AtomicInteger();
        deviceResponseList.forEach(deviceResponse -> {
            if (deviceResponse.getStatus() == 1) {
                online.getAndIncrement();
            } else {
                offline.getAndIncrement();
            }

            rexolarApiClient.getDeviceAttributes(deviceResponse.getDeviceId(), token, new String[]{Constants.PowerSwitch_1, Constants.TotalActivePower_1});

        });
        return BaseResponse.ok(new IndexCntNumResponse(deviceResponseList.size(), online.get(), offline.get(),
                deviceResponseList.size() - online.get() - offline.get()));
    }

    private List<DeviceResponse> getAirConList(List<SaasTslModel> tslModelList, Long spaceId, String token) {
        DeviceListRequest deviceListRequest = new DeviceListRequest();
        deviceListRequest.setSpaceInfoId(spaceId);
        deviceListRequest.setProductKeys(tslModelList.stream().map(SaasTslModel::getProductKey).collect(Collectors.toList()));
        deviceListRequest.setPageNo(1);
        deviceListRequest.setPageSize(10000);
        Page<DeviceResponse> page = deviceService.listV2(deviceListRequest, token);
        return page.getRecords();
    }

    @PostMapping("/page")
    @ResponseBody
    public BaseResponse page(HttpServletRequest  request, @RequestBody AirConPageRequest airConPageRequest) {
        log.info("page ===> airConPageRequest:{}", airConPageRequest);
        String token = request.getHeader("token");
        if (airConPageRequest.getSpaceInfoId()==null){
            log.error("page airConPageRequest.spaceId is null, airConPageRequest:{}", airConPageRequest);
            return BaseResponse.error("spaceId is null", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(airConPageRequest.getSpaceInfoId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("page validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        String tenantId = JwtUtils.getTenantId( token);
        List<SaasTslModel> tslModelList = tslModelService.queryTslModelByCategoryName(Constants.LIGHT, tenantId);
        if (CollectionUtils.isEmpty(tslModelList)){
            return BaseResponse.error("产品模型不存在", ResultCode.PARAM_ERROR);
        }
        DeviceListRequest deviceListRequest = new DeviceListRequest();
        BeanUtils.copyProperties(airConPageRequest, deviceListRequest);
        deviceListRequest.setProductKeys(tslModelList.stream().map(SaasTslModel::getProductKey).collect(Collectors.toList()));
        Page<DeviceResponse> page = deviceService.listV2(deviceListRequest, token);
        List<AirConResponse> airConResponses = new ArrayList<>();
        page.getRecords().forEach(deviceResponse -> {
            AirConResponse airConResponse = new AirConResponse();
            Map<String, Object> atrributes = rexolarApiClient.getDeviceAttributes(deviceResponse.getDeviceId(), token,
                    new String[]{Constants.PowerSwitch_1, Constants.MODE, Constants.SPEED, Constants.ROOM_TEMPERATURE, Constants.TEMPERATURE, Constants.RUN});
            if(!CollectionUtils.isEmpty(atrributes)){
                airConResponse.setMode(atrributes.get(Constants.MODE) != null?atrributes.get(Constants.MODE).toString():null);
                airConResponse.setSpeed(atrributes.get(Constants.SPEED) != null?atrributes.get(Constants.SPEED).toString():null);
                airConResponse.setRoomTemperature(atrributes.get(Constants.ROOM_TEMPERATURE) != null?atrributes.get(Constants.ROOM_TEMPERATURE).toString():null);
                airConResponse.setTemperature(atrributes.get(Constants.TEMPERATURE) != null?atrributes.get(Constants.TEMPERATURE).toString():null);
                airConResponse.setRun(atrributes.get(Constants.RUN) != null?atrributes.get(Constants.RUN).toString():null);
            }
            airConResponses.add(airConResponse);
        });
        Page<AirConResponse> responsePage = new Page<>(airConPageRequest.getPageNo(), airConPageRequest.getPageSize());
        BeanUtils.copyProperties(page, responsePage);
        responsePage.setRecords(airConResponses);
        return BaseResponse.ok(responsePage);
    }

    @PostMapping("/batchCmd")
    @ResponseBody
    public BaseResponse batchCmd(HttpServletRequest  request, @RequestBody AirBatchCmdRequest airBatchCmdRequest) {
        log.info("batchCmd ===> airBatchCmdRequest:{}", airBatchCmdRequest);
        String token = request.getHeader("token");
        if (airBatchCmdRequest.getSpaceId()==null){
            log.error("batchCmd airBatchCmdRequest.spaceId is null, airBatchCmdRequest:{}", airBatchCmdRequest);
            return BaseResponse.error("spaceId is null", ResultCode.PARAM_ERROR);
        }
        if(CollectionUtils.isEmpty(airBatchCmdRequest.getDeviceNames())){
            log.error("batchCmd airBatchCmdRequest.deviceNames is null, airBatchCmdRequest:{}", airBatchCmdRequest);
            return BaseResponse.error("设备列表不能为空", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(airBatchCmdRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("batchCmd validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        String tenantId = JwtUtils.getTenantId( token);
        List<String> deviceNames = spaceService.getDeviceNameList(airBatchCmdRequest.getSpaceId());
        for (String deviceName:airBatchCmdRequest.getDeviceNames()){
            if (!deviceNames.contains(deviceName)){
                log.error("batchCmd deviceName is not exist, deviceName:{}", deviceName);
                return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
            }
        }

        boolean flag = true;
        for (String deviceName:airBatchCmdRequest.getDeviceNames()){
            String [] devices = deviceName.split("_");
            if(devices.length==2){
                deviceName = devices[0];
            }
            BaseResponse result = controlDev(deviceName, airBatchCmdRequest.getCmd(), token);
            if(BaseResponse.ok().getCode()!=result.getCode()){
                log.error("batchCmd controlDev fail, deviceName:{}", deviceName);
                flag = false;
            }
        }
        return BaseResponse.ok(flag);
    }

    @PostMapping("/cmd")
    @ResponseBody
    public BaseResponse cmd(HttpServletRequest  request, @RequestBody AirConCmdRequest airConCmdRequest) {
        log.info("cmd ===> airCmdRequest:{}", airConCmdRequest);
        String token = request.getHeader("token");
        if (airConCmdRequest.getSpaceId()==null){
            log.error("cmd airCmdRequest.spaceId is null, airCmdRequest:{}", airConCmdRequest);
            return BaseResponse.error("spaceId is null", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isEmpty(airConCmdRequest.getDeviceName())){
            log.error("cmd airCmdRequest.deviceName is null, airCmdRequest:{}", airConCmdRequest);
            return BaseResponse.error("设备名称不能为空", ResultCode.PARAM_ERROR);
        }
        BaseResponse validateSpace = validateSpace(airConCmdRequest.getSpaceId(), token);
        if(BaseResponse.ok().getCode()!=validateSpace.getCode()){
            log.error("cmd validateSpace fail, validateSpace:{}", validateSpace);
            return validateSpace;
        }
        String tenantId = JwtUtils.getTenantId( token);
        String deviceName = airConCmdRequest.getDeviceName();
        if(deviceName.contains("_")){
            deviceName = deviceName.split("_")[0];
        }
        List<String> deviceNames = spaceService.getDeviceNameList(airConCmdRequest.getSpaceId());
        if (!deviceNames.contains(deviceName)){
            log.error("batchCmd deviceName is not exist, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        String [] devices = deviceName.split("_");
        if(devices.length==2){
            deviceName = devices[0];
        }
        return controlDev(deviceName, airConCmdRequest.getCmd(), token);
    }

    private BaseResponse controlDev(String deviceName, String cmd, String token) {
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, token);
        if(deviceBasicData==null){
            log.error("controlDev getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        PaasGatewayDeviceRelation relation = deviceService.getGwByDevcieName(deviceName);
        if(relation==null){
            log.error("controlDev getGwByDevcieName error, deviceName:{}", deviceName);
            return BaseResponse.error("网关不存在", ResultCode.PARAM_ERROR);
        }
        boolean flag = rexolarApiClient.updateDeviceAttributes(relation.getGwId(), ApiConstant.SHARED_SCOPE, JSON.toJSONString(cmd), token);
        if ( !flag){
            log.error("controlDev updateDeviceAttributes error, deviceName:{}", deviceName);
        }
        return BaseResponse.ok(flag);
    }

}
